/*CRC校验类
Created on 2020年05月10日
@author: zxyong 13738196011
 */

package com.zxy.common;

import java.io.UnsupportedEncodingException;

public class CRC_Check
{
	private String	CHAR_ENCODE	= "UTF-8";
	private byte[]	CRC			= new byte[2];
	private byte	data;
	private byte[]	reg			= new byte[2];
	private byte[]	ploy		= new byte[2];
	private byte	Op;

	public String CRC(String strTem) throws UnsupportedEncodingException
	{
		if(strTem.equals(""))
			return "";
		byte[] source = strTem.getBytes(CHAR_ENCODE);
		// 初始化多项式
		int temp = 0xA001;
		ploy = InttoByteArray(temp,2);
		// 初始化寄存器
		temp = 0xFFFF;
		reg = InttoByteArray(temp,2);

		for(int i = 0;i < source.length;i++)
		{
			// 获取数据
			data = source[i];
			// 与寄存器中数据进行异或操作
			reg[1] = (byte)(reg[1] ^ data);
			// 移动数据
			for(int j = 0;j < 8;j++)
			{
				// 获取数据的最后一位，即被移动出的数据判断是否与多项式异或
				Op = reg[0];
				// 右移一位
				reg = InttoByteArray(ByteArraytoInt(reg) >> 1,2);
				// 如果移出数据为1
				if((Op & 0x01) == 1)
				{
					// 与多项式进行异或操作
					reg[0] = (byte)(reg[0] ^ ploy[0]);
					reg[1] = (byte)(reg[1] ^ ploy[1]);
				}
			}
		}
		CRC = reg;
		return bytesToHexString(CRC);
	}

	public void CRC(byte[] source)
	{
		// 初始化多项式
		int temp = 0xA001;
		ploy = InttoByteArray(temp,2);
		// 初始化寄存器
		temp = 0xFFFF;
		reg = InttoByteArray(temp,2);

		for(int i = 0;i < source.length;i++)
		{
			// 获取数据
			data = source[i];
			// 与寄存器中数据进行异或操作
			reg[1] = (byte)(reg[1] ^ data);
			// 移动数据
			for(int j = 0;j < 8;j++)
			{
				// 获取数据的最后一位，即被移动出的数据判断是否与多项式异或
				Op = reg[0];
				// 右移一位
				reg = InttoByteArray(ByteArraytoInt(reg) >> 1,2);
				// 如果移出数据为1
				if((Op & 0x01) == 1)
				{
					// 与多项式进行异或操作
					reg[0] = (byte)(reg[0] ^ ploy[0]);
					reg[1] = (byte)(reg[1] ^ ploy[1]);
				}
			}
		}
		CRC = reg;
	}

	public byte[] getCRC()
	{
		return CRC;
	}

	// 格式化辅助函数
	private byte[] InttoByteArray(int iSource,int iArrayLen)
	{
		byte[] bLocalArr = new byte[iArrayLen];
		for(int i = 0;(i < 4) && (i < iArrayLen);i++)
		{
			bLocalArr[i] = (byte)(iSource >> 8 * i & 0xFF);
		}
		return bLocalArr;
	}

	private int ByteArraytoInt(byte[] bRefArr)
	{
		int iOutcome = 0;
		byte bLoop;

		for(int i = 0;i < bRefArr.length;i++)
		{
			bLoop = bRefArr[i];
			iOutcome += (bLoop & 0xFF) << (8 * i);

		}
		return iOutcome;
	}

	public String bytesToHexString(byte[] src)
	{
		StringBuilder stringBuilder = new StringBuilder("");
		if(src == null || src.length <= 0)
		{
			return null;
		}
		for(int i = 0;i < src.length;i++)
		{
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if(hv.length() < 2)
			{
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
}